home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / wasm223.zip / BASE.ASM < prev    next >
Assembly Source File  |  1993-05-04  |  29KB  |  923 lines

  1. ;********************************************************
  2. ; BASE -- By Eric Tauck
  3. ;
  4. ; This program pops up a window and allows numbers and
  5. ; characters to be entered and their hexadecimal and
  6. ; decimal equivalents displayed.  Use the up/down arrow
  7. ; or tab keys to switch between input fields.  Press ESC
  8. ; to exit and restore the screen.
  9. ;
  10. ; Base can be used as a run-it-when-you-want-it utility
  11. ; or installed as a TSR.  Base is invoked as follows:
  12. ;
  13. ;   BASE      run Base without installing as TSR
  14. ;   BASE /R   install Base as TSR
  15. ;   BASE /U   uninstall Base as TSR
  16. ;
  17. ; Base may not work properly on some adapters if the
  18. ; active video page is not zero.  See the note below on
  19. ; the -p switch when using Base with Brief.
  20. ;
  21. ; This program uses the WASM library files.
  22. ;
  23. ;--------------------------------------------------------
  24. ;
  25. ; You can call Base directly from the editor Brief
  26. ; (without making Base a TSR) with the following Brief
  27. ; macro:
  28. ;
  29. ;   base()
  30. ;   {
  31. ;     dos ("base.com >& nul", 0);
  32. ;   }
  33. ;
  34. ; Base must be somewhere on the current path.  Base
  35. ; will not work properly with Brief on some adapters
  36. ; unless the -p switch is used when starting Brief.  The
  37. ; -p switch forces Brief to use video page zero.
  38.  
  39.         INCLUDE 'library\case1.asm'
  40.         INCLUDE 'library\convert.asm'
  41.         INCLUDE 'library\draw1.asm'
  42.         INCLUDE 'library\shift.asm'
  43.         INCLUDE 'library\tsr1.asm'
  44.         INCLUDE 'library\tsr2.asm'
  45.         INCLUDE 'library\tsr3.asm'
  46.         INCLUDE 'library\video1.asm'
  47.         INCLUDE 'library\video3.asm'
  48.         INCLUDE 'library\video4.asm'
  49.         INCLUDE 'library\video5.asm'
  50.         INCLUDE 'library\video6.asm'
  51.         jmp     install
  52.  
  53. COLS    EQU     14              ;columns used
  54. ROWS    EQU     10              ;rows used
  55.  
  56. ;--- screen attributes
  57.  
  58. ATR1_BW         EQU     (WHITE * 16) OR BLACK           ;border color
  59. ATR2_BW         EQU     (WHITE * 16) OR BLACK           ;blank area color
  60. ATR3_BW         EQU     (WHITE * 16) OR BLACK           ;text color
  61. ATR4_BW         EQU     (BLACK * 16) OR WHITE OR BOLD   ;number color
  62. ATR5_BW         EQU     (BLACK * 16) OR WHITE OR BOLD   ;input color
  63. ATR6_BW         EQU     (WHITE * 16) OR BLACK           ;title color
  64.  
  65. ATR1_COL        EQU     (BLUE * 16) OR CYAN OR BOLD     ;border color
  66. ATR2_COL        EQU     (BLUE * 16) OR WHITE OR BOLD    ;blank area color
  67. ATR3_COL        EQU     (BLUE * 16) OR WHITE OR BOLD    ;text color
  68. ATR4_COL        EQU     (CYAN * 16) OR BROWN OR BOLD    ;number color
  69. ATR5_COL        EQU     (RED * 16) OR BROWN OR BOLD     ;input color
  70. ATR6_COL        EQU     (BLUE * 16) OR GREEN OR BOLD    ;title color
  71.  
  72. atr1            DB      ATR1_BW         ;
  73. atr2            DB      ATR2_BW         ;-- these are copied over by
  74. atr3            DB      ATR3_BW         ;   the 'colors' array below
  75. atr4            DB      ATR4_BW         ;   if a color video mode or
  76. atr5            DB      ATR5_BW         ;   adapter is detected
  77. atr6            DB      ATR6_BW         ;
  78.  
  79. ;--- input field array
  80.  
  81. input   DW      0
  82. inputs  DW      OFFSET HEX_inp, OFFSET DEC_inp, OFFSET CHR_inp
  83.  
  84. ;--- layout of input record
  85.  
  86. adjust  EQU     0       ;case adjustment
  87. valid   EQU     2       ;validate input
  88. recalc  EQU     4       ;recalculate total
  89. update  EQU     6       ;update input string
  90. locate  EQU     8       ;location
  91. inpbas  EQU     10      ;input base
  92. inpmax  EQU     12      ;input maximum
  93. inplen  EQU     14      ;input length
  94. inpptr  EQU     16      ;input pointer
  95.  
  96. ;--- hex input data
  97.  
  98. HEX_X   EQU     2
  99. HEX_Y   EQU     2
  100. HEX_MAX EQU     8
  101.  
  102. HEX_inp LABEL   WORD
  103.         DW      OFFSET HEX_adj          ;case adjustment
  104.         DW      OFFSET HEX_val          ;validate input
  105.         DW      OFFSET HEX_rec          ;recalculate total
  106.         DW      OFFSET HEX_upd          ;update input string
  107.         DW      (HEX_Y * 256) + HEX_X   ;location
  108.         DW      OFFSET HEX_base         ;input base
  109.         DW      HEX_MAX                 ;input maximum
  110.         DW      ?                       ;input length
  111.         DW      ?                       ;input pointer
  112.  
  113. ;--- decimal input data
  114.  
  115. DEC_X   EQU     2
  116. DEC_Y   EQU     5
  117. DEC_MAX EQU     10
  118.  
  119. DEC_inp LABEL   WORD
  120.         DW      OFFSET Dummy            ;case adjustment
  121.         DW      OFFSET DEC_val          ;validate input
  122.         DW      OFFSET DEC_rec          ;recalculate total
  123.         DW      OFFSET DEC_upd          ;update input string
  124.         DW      (DEC_Y * 256) + DEC_X   ;location
  125.         DW      OFFSET DEC_base         ;input base
  126.         DW      DEC_MAX                 ;input maximum
  127.         DW      ?                       ;input length
  128.         DW      ?                       ;input pointer
  129.  
  130. ;--- character input data
  131.  
  132. CHR_X   EQU     2
  133. CHR_Y   EQU     8
  134. CHR_MAX EQU     4
  135.  
  136. CHR_inp LABEL   WORD
  137.         DW      OFFSET Dummy            ;case adjustment
  138.         DW      OFFSET Dummy            ;validate input
  139.         DW      OFFSET CHR_rec          ;recalculate total
  140.         DW      OFFSET CHR_upd          ;update input string
  141.         DW      (CHR_Y * 256) + CHR_X   ;location
  142.         DW      OFFSET CHR_base         ;input base
  143.         DW      CHR_MAX                 ;input maximum
  144.         DW      ?                       ;input length
  145.         DW      ?                       ;input pointer
  146.  
  147. ;--- key commands
  148.  
  149. Commands LABEL  WORD
  150.         DW      4B00H, OFFSET Cmd_Left
  151.         DW      4D00H, OFFSET Cmd_Right
  152.         DW      4700H, OFFSET Cmd_Home
  153.         DW      4F00H, OFFSET Cmd_End
  154.         DW      4800H, OFFSET Cmd_Prev
  155.         DW      0F00H, OFFSET Cmd_Prev
  156.         DW      5000H, OFFSET Cmd_Next
  157.         DW      0F09H, OFFSET Cmd_Next
  158.         DW      0E08H, OFFSET Cmd_Bksp
  159.         DW      5300H, OFFSET Cmd_Delete
  160.         DW      0E7FH, OFFSET Cmd_Erase
  161.         DW      0
  162.  
  163. ;--- TSR data
  164.  
  165. TSR_ID1         EQU     4241H
  166. TSR_ID2         EQU     5345H
  167.  
  168. TSR_SHIFT       EQU     KEY_CTRL OR KEY_ALT     ;shift keys
  169.  
  170. TsrUsr          LABEL   BYTE
  171.                 DB      1, OFFSET Segment
  172.                 DB      0
  173.  
  174. TsrKey          LABEL   WORD
  175.                 DW      3000H, OFFSET Base      ;hot key, ALT-B
  176.                 DW      0
  177.  
  178. ;--- window text
  179.  
  180. tex1    DB      'BASE',0
  181. tex2    DB      'Hex',0
  182. tex3    DB      'Decimal',0
  183. tex4    DB      'Character',0
  184.  
  185. ;========================================
  186. ; Dummy routine.
  187.  
  188. Dummy   PROC    NEAR
  189.         clc
  190.         ret
  191.         ENDP
  192.  
  193. ;========================================
  194. ; Hex routines.
  195.  
  196. ;=== adjust
  197.  
  198. HEX_adj PROC    NEAR
  199.         cmp     al, 'a'         ;lower limit
  200.         jb      hexadj1
  201.         cmp     al, 'z'         ;upper limit
  202.         ja      hexadj1
  203.         and     al, NOT 20H     ;convert to upper case
  204. hexadj1 ret
  205.         ENDP
  206.  
  207. ;=== validate
  208.  
  209. HEX_val PROC    NEAR
  210.         cmp     al, '0'         ;lower number limit
  211.         jb      hexval1
  212.         cmp     al, '9'         ;upper number limit
  213.         jbe     hexval2
  214. hexval1 cmp     al, 'A'         ;lower letter limit
  215.         jb      hexval3
  216.         cmp     al, 'F'         ;upper letter limit
  217.         ja      hexval3
  218. hexval2 clc
  219.         ret
  220. hexval3 stc
  221.         ret
  222.         ENDP
  223.  
  224. ;=== recalculate, Out: DX:AX= total
  225.  
  226. HEX_rec PROC    NEAR
  227.         push    bx
  228.         mov     ax, OFFSET HEX_base     ;hex input buffer
  229.         mov     di, ax
  230.         add     di, [bx+inplen]         ;point to byte past end
  231.         mov     BYTE [di], 0            ;store NUL
  232.         mov     cx, 16                  ;base
  233.         call    Str2Num                 ;convert to string
  234.         pop     bx
  235.         ret
  236.         ENDP
  237.  
  238. ;=== update, set HEX_base and inplen, In: DX:AX= total
  239.  
  240. HEX_upd PROC    NEAR
  241.         push    bx
  242.         mov     cx, 16                  ;base
  243.         mov     si, OFFSET HEX_base     ;input buffer
  244.         mov     bx, si
  245.         call    Num2Str                 ;convert to string
  246.         pop     bx
  247.         mov     HEX_inp + inplen, ax    ;store length
  248.         ret
  249.         ENDP
  250.  
  251. ;========================================
  252. ; Decimal routines.
  253.  
  254. ;=== validate
  255.  
  256. DEC_val PROC    NEAR
  257.         cmp     al, '0'         ;lower limit
  258.         jb      decval1
  259.         cmp     al, '9'         ;upper limit
  260.         ja      decval1
  261.         clc
  262.         ret
  263. decval1 stc
  264.         ret
  265.         ENDP
  266.  
  267. ;=== recalculate, Out: DX:AX= total
  268.  
  269. DEC_rec PROC    NEAR
  270.         push    bx
  271.         mov     ax, OFFSET DEC_base     ;input buffer
  272.         mov     di, ax
  273.         add     di, [bx+inplen]         ;point to byte past end
  274.         mov     BYTE [di], 0            ;store NUL
  275.         mov     cx, 10                  ;base
  276.         call    Str2Num                 ;convert to string
  277.         jnc     decrec1                 ;exit if okay
  278.         mov     ax, 0FFFFH              ;max value FFFFFFFF
  279.         mov     dx, ax                  ;
  280. decrec1 pop     bx
  281.         ret
  282.         ENDP
  283.  
  284. ;=== update, set DEC_base and inplen, In: DX:AX= total
  285.  
  286. DEC_upd PROC    NEAR
  287.         push    bx
  288.         mov     cx, 10                  ;base
  289.         mov     si, OFFSET DEC_base     ;input buffer
  290.         mov     bx, si
  291.         call    Num2Str                 ;convert to string
  292.         pop     bx
  293.         mov     DEC_inp + inplen, ax    ;store length
  294.         ret
  295.         ENDP
  296.  
  297. ;========================================
  298. ; Character routines.
  299.  
  300. ;=== recalculate,  Out: DX:AX= total
  301.  
  302. CHR_rec PROC    NEAR
  303.         cld
  304.         sub     ax, ax                  ;zero total
  305.         mov     dx, ax                  ;
  306.         mov     cx, CHR_inp + inplen    ;get length
  307.         jcxz    chrrec2                 ;exit if zero bytes
  308.         mov     si, OFFSET CHR_base     ;input buffer
  309. chrrec1 mov     dh, dl                  ;
  310.         mov     dl, ah                  ;-- shift 32 bit value
  311.         mov     ah, al                  ;
  312.         lodsb                           ;load lower byte
  313.         loop    chrrec1                 ;loop for each character
  314. chrrec2 ret
  315.         ENDP
  316.  
  317. ;=== update, set CHR_base and inplen, In: DX:AX= total
  318.  
  319. CHR_upd PROC    NEAR
  320.         cld                             ;forward direction
  321.         mov     di, OFFSET CHR_base     ;input buffer
  322.         mov     cx, 4                   ;number of characters
  323.  
  324. ;--- skip preceding zeros
  325.  
  326. chrupd1 or      dh, dh                  ;check if zero
  327.         jnz     chrupd2                 ;exit if not
  328.         mov     dh, dl                  ;
  329.         mov     dl, ah                  ;-- shift 32 bit value
  330.         mov     ah, al                  ;
  331.         loop    chrupd1                 ;loop until all bytes
  332.  
  333. chrupd2 mov     CHR_inp + inplen, cx    ;store length
  334.         jcxz    chrupd4                 ;exit if no bytes
  335.  
  336. chrupd3 mov     [di], dh                ;store upper byte
  337.         inc     di                      ;increment pointer
  338.         mov     dh, dl                  ;
  339.         mov     dl, ah                  ;-- shift 32 bit value
  340.         mov     ah, al                  ;
  341.         loop    chrupd3                 ;loop until all bytes
  342.  
  343. chrupd4 ret
  344.         ENDP
  345.  
  346. ;========================================
  347. ; Left.
  348.  
  349. Cmd_Left PROC   NEAR
  350.         cmp     WORD [bx+inpptr], 0     ;check if at edge
  351.         je      cmdlef1                 ;exit if so
  352.         dec     WORD [bx+inpptr]        ;move left
  353. cmdlef1 clc
  354.         ret
  355.         ENDP
  356.  
  357. ;========================================
  358. ; Right.
  359.  
  360. Cmd_Right PROC  NEAR
  361.         mov     ax, [bx+inplen]         ;load bytes in buffer
  362.         cmp     ax, [bx+inpmax]         ;check if past edge
  363.         jne     cmdrig1
  364.         dec     ax                      ;real edge
  365. cmdrig1 cmp     ax, [bx+inpptr]         ;check if at edge
  366.         je      cmdrig2                 ;exit if so
  367.         inc     WORD [bx+inpptr]        ;move right
  368. cmdrig2 clc
  369.         ret
  370.         ENDP
  371.  
  372. ;========================================
  373. ; Home.
  374.  
  375. Cmd_Home PROC   NEAR
  376.         mov     WORD [bx+inpptr], 0     ;move home
  377.         clc
  378.         ret
  379.         ENDP
  380.  
  381. ;========================================
  382. ; End.
  383.  
  384. Cmd_End PROC    NEAR
  385.         mov     ax, [bx+inpmax]         ;maximum input
  386.         dec     ax                      ;real edge
  387.         cmp     ax, [bx+inplen]         ;check if filled
  388.         jbe     cmdend1                 ;exit if so, use this edge
  389.         mov     ax, [bx+inplen]         ;use end of bytes
  390. cmdend1 mov     [bx+inpptr], ax         ;move end
  391.         ret
  392.         clc
  393.         ENDP
  394.  
  395. ;========================================
  396. ; Previous.
  397.  
  398. Cmd_Prev PROC   NEAR
  399.         sub     input, 1        ;decrement index
  400.         jnc     cmdpre1         ;exit if okay
  401.         mov     input, 2        ;last index
  402. cmdpre1 stc
  403.         ret
  404.         ENDP
  405.  
  406. ;========================================
  407. ; Next.
  408.  
  409. Cmd_Next PROC   NEAR
  410.         inc     input           ;increment index
  411.         cmp     input, 2        ;check if past end
  412.         jbe     cmdnex1         ;exit if okay
  413.         mov     input, 0        ;restart with first
  414. cmdnex1 stc
  415.         ret
  416.         ENDP
  417.  
  418. ;========================================
  419. ; Backspace.
  420.  
  421. Cmd_Bksp PROC  NEAR
  422.         cmp     WORD [bx+inpptr], 0     ;check if at edge
  423.         je      cmdbks1                 ;exit if so
  424.         dec     WORD [bx+inpptr]        ;move left
  425.         call    Delete                  ;delete
  426. cmdbks1 stc
  427.         ret
  428.         ENDP
  429.  
  430. ;========================================
  431. ; Delete.
  432.  
  433. Cmd_Delete PROC NEAR
  434.         call    Delete          ;delete character
  435.         stc
  436.         ret
  437.         ENDP
  438.  
  439. ;========================================
  440. ; Erase.
  441.  
  442. Cmd_Erase PROC  NEAR
  443.         mov     empty, 0        ;zero all inputs
  444.         stc
  445.         ret
  446.         ENDP
  447.  
  448. ;========================================
  449. ; Delete a character from a buffer.
  450. ;
  451. ; In: BX= input pointer.
  452.  
  453. Delete  PROC    NEAR
  454.         mov     cx, [bx+inplen]         ;load bytes
  455.         mov     si, [bx+inpptr]         ;load pointer
  456.         sub     cx, si                  ;get bytes to shift
  457.         jz      delete1                 ;jump if at end
  458.         dec     cx                      ;delete this byte
  459.         add     si, [bx+inpbas]         ;point to byte to delete
  460.         mov     di, si
  461.         inc     si                      ;point to next byte
  462.         cld
  463.         rep
  464.         movsb                           ;shift bytes left
  465.         dec     WORD [bx+inplen]        ;reduce length
  466.         jnz     delete1                 ;exit if not zero
  467.         mov     empty, 0                ;erase all inputs
  468. delete1 ret
  469.         ENDP
  470.  
  471. ;========================================
  472. ; Insert a character into a buffer.
  473. ;
  474. ; In: AL= character; BX= input pointer.
  475.  
  476. Insert  PROC    NEAR
  477.         mov     dx, [bx+inpmax]         ;maximum input
  478.         mov     cx, [bx+inplen]         ;current bytes
  479.         mov     si, [bx+inpbas]         ;input buffer
  480.         mov     di, [bx+inpptr]         ;current pointer
  481.         add     di, si                  ;current byte
  482.  
  483.         cmp     dx, cx                  ;check if buffer full
  484.         je      insert1                 ;skip shift if so
  485.  
  486.         push    di
  487.         add     si, cx                  ;point to byte past end
  488.         mov     di, si
  489.         dec     si                      ;point to last byte
  490.         sub     cx, [bx+inpptr]         ;bytes to shift
  491.         std
  492.         rep
  493.         movsb                           ;shift bytes to right
  494.         inc     WORD [bx+inplen]        ;increment length
  495.         pop     di
  496.  
  497. ;--- store character
  498.  
  499. insert1 cld
  500.         stosb                           ;store character
  501.         dec     dx                      ;last location
  502.         cmp     dx, [bx+inpptr]         ;check if at end
  503.         je      insert2
  504.         inc     WORD [bx+inpptr]        ;increment pointer
  505.  
  506. insert2 mov     empty, 1                ;set non-empty flag
  507.         ret
  508.         ENDP
  509.  
  510. ;========================================
  511. ; Display a buffer.
  512. ;
  513. ; In: SI= input pointer; BX= current
  514. ;     input pointer.
  515.  
  516. Display PROC    NEAR
  517.         push    bx
  518.  
  519. ;--- set color
  520.  
  521.         mov     al, atr4                ;non-active attribute
  522.         cmp     si, bx                  ;check if this is active input
  523.         jne     displa1
  524.         mov     al, atr5                ;active attribute
  525. displa1 call    AtrSet                  ;set color
  526.  
  527. ;--- clear to end of buffer or whole buffer
  528.  
  529.         mov     di, [si+inpbas]         ;input buffer
  530.         mov     cx, [si+inpmax]         ;maximum characters
  531.         sub     dx, dx                  ;empty length
  532.  
  533.         cmp     empty, 0                ;check if empty
  534.         je      displa2                 ;jump if so
  535.  
  536.         mov     dx, [si+inplen]         ;length
  537.         add     di, dx                  ;byte past end
  538.         sub     cx, dx                  ;bytes after end
  539.  
  540. displa2 mov     al, ' '                 ;space
  541.         cld
  542.         rep
  543.         stosb                           ;fill with spaces
  544.         mov     [si+inplen], dx         ;save length, might be reset
  545.  
  546. ;--- display
  547.  
  548.         mov     ax, base_xy             ;base coordinates
  549.         add     ax, [si+locate]         ;input location
  550.         call    CurMov                  ;position cursor
  551.         mov     ax, [si+inpbas]         ;buffer address
  552.         mov     cx, [si+inpmax]         ;buffer size
  553.         call    WrtStrc                 ;display
  554.  
  555.         pop     bx
  556.         ret
  557.         ENDP
  558.  
  559. ;========================================
  560. ; Move the cursor to the current
  561. ; location.
  562. ;
  563. ; In: BX= input pointer.
  564.  
  565. Cursor  PROC    NEAR
  566.         push    bx
  567.  
  568. ;--- check if pointer is past end
  569.  
  570.         mov     ax, [bx+inpmax]         ;buffer size
  571.         dec     ax                      ;end location
  572.         cmp     ax, [bx+inplen]         ;check if buffer filled
  573.         jbe     cursor1
  574.         mov     ax, [bx+inplen]         ;use end of bytes
  575. cursor1 cmp     ax, [bx+inpptr]         ;check if pointer is okay
  576.         jae     cursor2
  577.         mov     [bx+inpptr], ax         ;fix pointer
  578.  
  579. ;--- position cursor
  580.  
  581. cursor2 mov     ax, base_xy             ;base address
  582.         add     ax, [bx+locate]         ;start of input
  583.         add     ax, [bx+inpptr]         ;current location
  584.         call    CurMov                  ;position cursor
  585.         pop     bx
  586.         ret
  587.         ENDP
  588.  
  589. ;========================================
  590. ; Load the window coordinates.
  591.  
  592. Coords  PROC    NEAR
  593.         mov     bx, base_xy                     ;upper left
  594.         mov     cx, bx
  595.         add     cx, ((ROWS-1)*256)+(COLS-1)     ;lower right
  596.         mov     dx, ds                          ;current segment
  597.         mov     ax, OFFSET screen               ;screen save area
  598.         ret
  599.         ENDP
  600.  
  601. ;========================================
  602. ; Main routine.
  603.  
  604. Base    PROC    NEAR
  605.         mov     empty, 0                ;no input
  606.         mov     tot_lo, 0               ;zero total
  607.         mov     tot_hi, 0               ;
  608.  
  609. ;--- initialize video
  610.  
  611.         call    VidInit                 ;initialize video routines
  612.         jnc     base1
  613.         jmp     baseB
  614.  
  615. base1   call    ModDim                  ;current columns and rows
  616.         sub     al, COLS + 1            ;starting column
  617.         mov     ah, 1                   ;starting row
  618.         mov     base_xy, ax             ;save save it
  619.  
  620. ;--- save screen area
  621.  
  622.         call    CurPos                  ;get cursor position
  623.         push    ax                      ;save on stack
  624.  
  625.         call    Coords                  ;load coordinates
  626.         call    ScrGet                  ;save
  627.  
  628. ;--- draw screen
  629.  
  630.         mov     al, atr2
  631.         call    AtrSet
  632.  
  633.         call    Coords
  634.         call    ScrClr
  635.  
  636.         mov     al, atr1
  637.         call    AtrSet
  638.  
  639.         call    Coords
  640.         call    DrwBox
  641.  
  642.         mov     al, atr6
  643.         call    AtrSet
  644.  
  645.         mov     ax, base_xy
  646.         add     al, 5
  647.         call    CurMov
  648.         mov     ax, OFFSET tex1
  649.         call    WrtStr
  650.  
  651.         mov     al, atr3
  652.         call    AtrSet
  653.  
  654.         mov     ax, base_xy
  655.         add     ax, 0102H
  656.         call    CurMov
  657.         mov     ax, OFFSET tex2
  658.         call    WrtStr
  659.  
  660.         mov     ax, base_xy
  661.         add     ax, 0402H
  662.         call    CurMov
  663.         mov     ax, OFFSET tex3
  664.         call    WrtStr
  665.  
  666.         mov     ax, base_xy
  667.         add     ax, 0702H
  668.         call    CurMov
  669.         mov     ax, OFFSET tex4
  670.         call    WrtStr
  671.  
  672. ;=== loop until escape
  673.  
  674. ;--- update strings if some input
  675.  
  676. base2   mov     bx, input               ;input record index
  677.         shl     bx, 1                   ;times two
  678.         mov     bx, [inputs + bx]       ;load input record
  679.         
  680.         cmp     empty, 0                ;check if empty
  681.         je      base3                   ;skip update if so
  682.  
  683.         mov     ax, tot_lo
  684.         mov     dx, tot_hi
  685.         call    HEX_inp + update        ;update hex number
  686.         mov     ax, tot_lo
  687.         mov     dx, tot_hi
  688.         call    DEC_inp + update        ;update decimal number
  689.         mov     ax, tot_lo
  690.         mov     dx, tot_hi
  691.         call    CHR_inp + update        ;update characters
  692.  
  693. ;--- redisplay all inputs
  694.  
  695. base3   mov     si, OFFSET HEX_inp
  696.         call    Display                 ;display hex number
  697.         mov     si, OFFSET DEC_inp
  698.         call    Display                 ;display decimal number
  699.         mov     si, OFFSET CHR_inp
  700.         call    Display                 ;display characters
  701.  
  702. base4   call    Cursor                  ;current cursor location
  703.  
  704. ;--- wait for keystroke
  705.  
  706. base5   sub     ah, ah                  ;read key function
  707.         int     16H                     ;execute
  708.  
  709.         cmp     al, 27                  ;check if exit
  710.         je      baseA                   ;jump if so
  711.  
  712.         mov     si, OFFSET Commands     ;command table
  713. base6   cmp     WORD [si], 0            ;check if end of table
  714.         je      base8
  715.         cmp     WORD [si], ax           ;check if key matches
  716.         je      base7
  717.         add     si, 4                   ;next entry
  718.         jmps    base6                   ;loop back
  719.  
  720. base7   call    WORD [si + 2]           ;call command
  721.         jnc     base4                   ;jump if cursor movement only
  722.         jmps    base9                   ;jump if recalculate and display
  723.  
  724. ;--- insert character
  725.  
  726. base8   or      al, al                  ;check extended key
  727.         jz      base5                   ;skip if so
  728.         call    WORD [bx+adjust]        ;adjust character (make upper case)
  729.         call    WORD [bx+valid]         ;validate character
  730.         jc      base5                   ;skip if invalid
  731.         call    Insert                  ;insert into buffer
  732.  
  733. base9   call    WORD [bx+recalc]        ;recalculate total
  734.         mov     tot_lo, ax              ;save low word
  735.         mov     tot_hi, dx              ;save high word
  736.         jmp     base2
  737.  
  738. ;=== finished
  739.  
  740. ;--- restore screen area
  741.  
  742. baseA   call    Coords                  ;load coordinates
  743.         call    ScrPut                  ;restore
  744.  
  745.         pop     ax
  746.         call    CurMov                  ;restore cursor
  747. baseB   ret
  748.         ENDP
  749.  
  750. ;========================================
  751. ; Resident query routine. Return the
  752. ; segement to uninstall.
  753.  
  754. Segment PROC    NEAR
  755.         mov     dx, ds
  756.         ret
  757.         ENDP
  758.  
  759. ;========================================
  760. ; Uninitialized data.
  761.  
  762. ORG_FIX EQU     $
  763.  
  764. base_xy LABEL   WORD                    ;base x and y coordinates
  765.         ORG     +2
  766.  
  767. empty   LABEL   BYTE                    ;zero if no input
  768.         ORG     +1
  769.  
  770. tot_lo  LABEL   WORD                    ;low word of total
  771.         ORG     +2
  772.  
  773. tot_hi  LABEL   WORD                    ;high word of total
  774.         ORG     +2
  775.  
  776. screen  LABEL   BYTE                    ;screen save area
  777.         ORG     +(ROWS * COLS * 2)
  778.  
  779. HEX_base LABEL  BYTE                    ;hex i/o buffer
  780.         ORG     +(HEX_MAX+1)
  781.  
  782. DEC_base LABEL  BYTE                    ;decimal i/o buffer
  783.         ORG     +(DEC_MAX+1)
  784.  
  785. CHR_base LABEL  BYTE                    ;character i/o buffer
  786.         ORG     +(CHR_MAX+1)
  787.  
  788. TSR_END
  789.  
  790.         ORG     ORG_FIX
  791.  
  792. ;========================================
  793. ; Transient data.
  794.  
  795. banner  DB      13,10,'BASE  Version 1.00  By Eric Tauck',0
  796. okay    DB      13,10,'Base installed, press ALT-CTL-B to invoke',0
  797. uninst  DB      13,10,'Base removed from memory',0
  798. error1  DB      13,10,'Parameter error, run BASE ? for help',0
  799. error2  DB      13,10,'Error: Already installed',0
  800. error3  DB      13,10,'Error: Not installed',0
  801. error4  DB      13,10,'Error: Cannot uninstall',0
  802.  
  803. help    DB      13,10
  804.         DB      'Usage: BASE [option]',13,10
  805.         DB      13,10
  806.         DB      ' /R  resident mode',13,10
  807.         DB      ' /U  uninstall'
  808.         DB      0
  809.  
  810. colors  DB      ATR1_COL, ATR2_COL, ATR3_COL, ATR4_COL, ATR5_COL, ATR6_COL
  811.  
  812. ;========================================
  813. ; Installation.
  814.  
  815. ;--- transient library files
  816.  
  817. install INCLUDE 'library\start.asm'
  818.         INCLUDE 'library\case2.asm'
  819.         INCLUDE 'library\memory.asm'
  820.         INCLUDE 'library\message1.asm'
  821.         INCLUDE 'library\intr.asm'
  822.         INCLUDE 'library\parms.asm'
  823.         INCLUDE 'library\video2.asm'
  824.         INCLUDE 'library\video8.asm'
  825.  
  826. ;--- determine attributes to use
  827.  
  828.         call    VidCol                  ;check if color adapter
  829.         jnc     instal1                 ;skip if not
  830.         mov     si, OFFSET colors
  831.         mov     di, OFFSET atr1
  832.         mov     cx, 6
  833.         cld
  834.         rep
  835.         movsb                           ;copy color attributes to atr1-6
  836.  
  837. ;--- check if already installed
  838.  
  839. instal1 sub     si, si                  ;zero if not installed
  840.         Query   1                       ;query
  841.         jc      instal2                 ;skip if not installed
  842.         mov     si, dx                  ;save segment
  843.  
  844. ;--- check parameters
  845.  
  846. instal2 call    ParGet                  ;get parameter
  847.         jc      instal5
  848.  
  849.         push    ax
  850.         mov     ax, OFFSET banner       ;banner
  851.         call    MesPutL                 ;display only if parameters
  852.         pop     ax
  853.  
  854.         push    ax
  855.         call    StrUpr                  ;convert to upper case
  856.         pop     bx
  857.         mov     ax, [bx]                ;load first two bytes
  858.  
  859.         cmp     al, '?'
  860.         je      instal4
  861.         cmp     ah, '?'
  862.         je      instal4
  863.         cmp     ax, '/H'
  864.         je      instal4
  865.         cmp     ax, '/R'
  866.         je      instal7
  867.         cmp     ax, '/U'
  868.         je      instal8
  869.  
  870. ;=== error in parameters
  871.  
  872.         mov     ax, OFFSET error1
  873.  
  874. instal3 call    MesPutL                 ;display error message
  875.         mov     ax, 4CFFH               ;exit function with error
  876.         int     21H                     ;execute
  877.  
  878. ;--- display help
  879.  
  880. instal4 mov     ax, OFFSET help         ;help message
  881.         jmps    instal3
  882.  
  883. ;--- run non-resident
  884.  
  885. instal5 call    Base                    ;run program
  886.  
  887. instal6 mov     ax, 4C00H               ;exit function
  888.         int     21H                     ;execute
  889.  
  890. ;--- make resident
  891.  
  892. instal7 mov     ax, OFFSET error2       ;possible error message
  893.         or      si, si                  ;check if already installed
  894.         jnz     instal3                 ;jump if so
  895.  
  896.         mov     ax, OFFSET okay
  897.         call    MesPutL                 ;display installed message
  898.  
  899.         Trap21                          ;hook interrupt 21
  900.         Trap16                          ;hook interrupt 16
  901.         Keep                            ;make resident
  902.  
  903. ;--- uninstall
  904.  
  905. instal8 mov     ax, OFFSET error3       ;possible error message
  906.         or      si, si                  ;check resident
  907.         jz      instal3                 ;jump if not
  908.  
  909.         Okay16  si                      ;verify
  910.         jne     instal9
  911.         Okay21  si                      ;verify
  912.         jne     instal9
  913.         Free16  si                      ;release interrupt 16
  914.         Free21  si                      ;release interrupt 21
  915.         mov     ax, si
  916.         call    MemRel                  ;release memory
  917.         mov     ax, OFFSET uninst
  918.         call    MesPutL                 ;display message
  919.         jmp     instal6
  920.  
  921. instal9 mov     ax, OFFSET error4       ;error message
  922.         jmp     instal3
  923.